import bcrypt from 'bcryptjs';
import { UserService } from './UserService';
import { CreditService } from './CreditService';
import { User } from '../entities/User';
import { generateAccessToken, generateRefreshToken } from '../config/jwt';
import { verifyGoogleCode } from '../config/google';
import { verifyGitHubCode } from '../config/github';
import { JwtPayload, AuthResponse } from '../types';

export class AuthService {
  private userService: UserService;
  private creditService: CreditService;

  constructor() {
    this.userService = new UserService();
    this.creditService = new CreditService();
  }

  /**
   * 用户注册
   */
  async register(userData: {
    username?: string;
    email: string;
    password: string;
    firstName?: string;
    lastName?: string;
  }): Promise<AuthResponse> {
    // 检查邮箱是否已存在
    const existingUser = await this.userService.findUserByEmail(userData.email);
    if (existingUser) {
      throw new Error('邮箱地址已被注册');
    }

    // 检查用户名是否已存在（如果提供了用户名）
    if (userData.username) {
      const existingUsername = await this.userService.findUserByUsername(userData.username);
      if (existingUsername) {
        throw new Error('用户名已被使用');
      }
    }

    // 创建用户
    const user = await this.userService.createUser({
      ...userData,
      provider: 'local',
      isActive: true,
    });

    // 为新用户赠送5点积分
    try {
      await this.creditService.addCredits({
        userId: user.id,
        credits: 5,
        validDays: 365, // 积分有效期1年
        description: '新用户注册赠送积分',
        referenceId: `register_${user.id}`,
        metadata: {
          type: 'registration_bonus',
          registrationDate: new Date().toISOString()
        }
      });
    } catch (error) {
      console.error('赠送新用户积分失败:', error);
      // 不影响注册流程，只记录错误
    }

    // 生成JWT token
    const tokenPayload: Omit<JwtPayload, 'iat' | 'exp'> = {
      userId: user.id,
      email: user.email,
      role: 'user', // 默认角色为用户
    };

    const accessToken = generateAccessToken(tokenPayload);
    const refreshToken = generateRefreshToken(tokenPayload);

    return {
      token: accessToken,
      refreshToken,
      user: this.sanitizeUser(user),
    };
  }

  /**
   * 用户登录
   */
  async login(email: string, password: string): Promise<AuthResponse> {
    // 查找用户
    const user = await this.userService.findUserByEmail(email);
    if (!user) {
      throw new Error('邮箱或密码错误');
    }

    if (!user.isActive) {
      throw new Error('账户已被禁用');
    }

    if (user.provider !== 'local') {
      throw new Error('此账户使用第三方登录，请使用相应的登录方式');
    }

    // 验证密码
    const isPasswordValid = await this.userService.verifyPassword(user, password);
    if (!isPasswordValid) {
      throw new Error('邮箱或密码错误');
    }

    // 生成JWT token
    const tokenPayload: Omit<JwtPayload, 'iat' | 'exp'> = {
      userId: user.id,
      email: user.email,
      role: 'user', // 可以从数据库获取用户角色
    };

    const accessToken = generateAccessToken(tokenPayload);
    const refreshToken = generateRefreshToken(tokenPayload);

    return {
      token: accessToken,
      refreshToken,
      user: this.sanitizeUser(user),
    };
  }

  /**
   * Google OAuth登录
   */
  async googleLogin(code: string): Promise<AuthResponse> {
    // 使用授权码获取Google用户信息
    const googleUserInfo = await verifyGoogleCode(code);

    // 查找现有用户（通过Google ID或邮箱）
    let user = await this.userService.findUserByEmail(googleUserInfo.email!);

    if (user) {
      // 用户已存在
      if (user.provider === 'local') {
        // 如果是本地账户，更新为Google账户
        user = await this.userService.updateUser(user.id, {
          googleId: googleUserInfo.googleId,
          provider: 'google',
          picture: googleUserInfo.picture,
          firstName: googleUserInfo.givenName || user.firstName,
          lastName: googleUserInfo.familyName || user.lastName,
        });
      } else if (user.googleId !== googleUserInfo.googleId) {
        // Google ID不匹配
        throw new Error('账户验证失败');
      }
    } else {
      // 创建新用户
      user = await this.userService.createUser({
        email: googleUserInfo.email!,
        username: googleUserInfo.email,
        googleId: googleUserInfo.googleId,
        provider: 'google',
        firstName: googleUserInfo.givenName,
        lastName: googleUserInfo.familyName,
        picture: googleUserInfo.picture,
        password: "123456",
        isActive: true,
      });

      // 为新用户赠送5点积分
      try {
        await this.creditService.addCredits({
          userId: user.id,
          credits: 5,
          validDays: 365, // 积分有效期1年
          description: '新用户注册赠送积分',
          referenceId: `google_register_${user.id}`,
          metadata: {
            type: 'registration_bonus',
            provider: 'google',
            registrationDate: new Date().toISOString()
          }
        });
      } catch (error) {
        console.error('赠送新用户积分失败:', error);
        // 不影响注册流程，只记录错误
      }
    }

    if (!user!.isActive) {
      throw new Error('账户已被禁用');
    }

    // 生成JWT token
    const tokenPayload: Omit<JwtPayload, 'iat' | 'exp'> = {
      userId: user!.id,
      email: user!.email,
      role: 'user',
    };

    const accessToken = generateAccessToken(tokenPayload);
    const refreshToken = generateRefreshToken(tokenPayload);

    return {
      token: accessToken,
      refreshToken,
      user: this.sanitizeUser(user!),
    };
  }

  /**
   * GitHub OAuth登录
   */
  async githubLogin(code: string): Promise<AuthResponse> {
    // 验证GitHub授权码并获取用户信息
    const githubUserInfo = await verifyGitHubCode(code);

    // 查找现有用户（通过GitHub ID或邮箱）
    let user = await this.userService.findUserByEmail(githubUserInfo.email!);

    if (user) {
      // 用户已存在
      if (user.provider === 'local') {
        // 如果是本地账户，更新为GitHub账户
        user = await this.userService.updateUser(user.id, {
          githubId: githubUserInfo.githubId,
          provider: 'github',
          picture: githubUserInfo.picture,
          firstName: githubUserInfo.name?.split(' ')[0] || user.firstName,
          lastName: githubUserInfo.name?.split(' ').slice(1).join(' ') || user.lastName,
        });
      } else if (user.githubId !== githubUserInfo.githubId) {
        // GitHub ID不匹配
        throw new Error('账户验证失败');
      }
    } else {
      // 创建新用户
      const nameParts = githubUserInfo.name?.split(' ') || [];
      user = await this.userService.createUser({
        email: githubUserInfo.email!,
        username: githubUserInfo.username || githubUserInfo.email,
        githubId: githubUserInfo.githubId,
        provider: 'github',
        firstName: nameParts[0] || githubUserInfo.username,
        lastName: nameParts.slice(1).join(' ') || '',
        picture: githubUserInfo.picture,
        password: "123456",
        isActive: true,
      });

      // 为新用户赠送5点积分
      try {
        await this.creditService.addCredits({
          userId: user.id,
          credits: 5,
          validDays: 365, // 积分有效期1年
          description: '新用户注册赠送积分',
          referenceId: `github_register_${user.id}`,
          metadata: {
            type: 'registration_bonus',
            provider: 'github',
            registrationDate: new Date().toISOString()
          }
        });
      } catch (error) {
        console.error('赠送新用户积分失败:', error);
        // 不影响注册流程，只记录错误
      }
    }

    if (!user!.isActive) {
      throw new Error('账户已被禁用');
    }

    // 生成JWT token
    const tokenPayload: Omit<JwtPayload, 'iat' | 'exp'> = {
      userId: user!.id,
      email: user!.email,
      role: 'user',
    };

    const accessToken = generateAccessToken(tokenPayload);
    const refreshToken = generateRefreshToken(tokenPayload);

    return {
      token: accessToken,
      refreshToken,
      user: this.sanitizeUser(user!),
    };
  }

  /**
   * 刷新token
   */
  async refreshToken(refreshTokenString: string): Promise<{ token: string; refreshToken: string }> {
    try {
      // 这里需要导入验证刷新token的函数
      const { verifyRefreshToken } = await import('../config/jwt');
      const payload = verifyRefreshToken(refreshTokenString);

      // 验证用户是否仍然存在且活跃
      const user = await this.userService.findUserById(payload.userId);
      if (!user || !user.isActive) {
        throw new Error('用户不存在或已被禁用');
      }

      // 生成新的token
      const tokenPayload: Omit<JwtPayload, 'iat' | 'exp'> = {
        userId: user.id,
        email: user.email,
        role: payload.role,
      };

      const newAccessToken = generateAccessToken(tokenPayload);
      const newRefreshToken = generateRefreshToken(tokenPayload);

      return {
        token: newAccessToken,
        refreshToken: newRefreshToken,
      };
    } catch (error) {
      throw new Error('刷新token失败');
    }
  }

  /**
   * 获取当前用户信息
   */
  async getCurrentUser(userId: number): Promise<any> {
    const user = await this.userService.findUserById(userId);
    if (!user) {
      throw new Error('用户不存在');
    }
    return this.sanitizeUser(user);
  }

  /**
   * 清理用户敏感信息
   */
  private sanitizeUser(user: User): any {
    const { password, ...sanitizedUser } = user;
    return sanitizedUser;
  }

  /**
   * 修改密码
   */
  async changePassword(userId: number, oldPassword: string, newPassword: string): Promise<void> {
    const user = await this.userService.findUserById(userId);
    if (!user) {
      throw new Error('用户不存在');
    }

    if (user.provider !== 'local') {
      throw new Error('第三方登录用户无法修改密码');
    }

    // 验证旧密码
    const isOldPasswordValid = await this.userService.verifyPassword(user, oldPassword);
    if (!isOldPasswordValid) {
      throw new Error('原密码错误');
    }

    // 更新密码
    await this.userService.updateUser(userId, { password: newPassword });
  }

  /**
   * 重置密码（需要邮箱验证，这里简化处理）
   */
  async resetPassword(email: string, newPassword: string): Promise<void> {
    const user = await this.userService.findUserByEmail(email);
    if (!user) {
      throw new Error('用户不存在');
    }

    if (user.provider !== 'local') {
      throw new Error('第三方登录用户无法重置密码');
    }

    await this.userService.updateUser(user.id, { password: newPassword });
  }
}